# StartTCL: n
#
#
# This file is part of the StartTCL Startup System
#
# StartTCL is (c) 2006 by Lazarus Long <lazarus.long@bigfoot.com>
# StartTCL is (c) 2006 by Spirit <thehiddenspirit@hotmail.com>
#
# StartTCL is free software; you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation; either version 2.1 of the License, or (at your option)
# any later version.
#
# StartTCL is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. You can also consult
# the terms of the license at:
#
#		<http://www.gnu.org/copyleft/lesser.html>
#
#
# Name:		ngChanneling.tcl
#
# Version:	0.1.1
#
# Date:		2006-05-29
#
# Description:	NextGen Channeling and AutoShot System
#
# Authors:	Spirit <thehiddenspirit@hotmail.com>
#		Lazarus Long <lazarus.long@bigfoot.com>
#
# Credits:	Seatleson (spell patch and original script concept)
#
#


#
#	Patch to apply to spells.dbc
#
# channeling spells to be used with DBC-Patcher
#
#;< cut from here down and remove the hash "#" from the begining of all lines >
# ;AutoShot
# 75:60=77
# 5019:60=77
#
# ;Blizzard
# ;Rank 1
# 10:28=36,30=40,58=2,59=6,60=77,80=28,86=14,88=0,89=3,91=0
# ;Rank 2
# 6141:28=36,30=65,58=2,59=6,60=77,80=28,86=14,88=0,89=3,91=0
# ;Rank 3
# 8427:28=36,30=90,58=2,59=6,60=77,80=28,86=14,88=0,89=3,91=0
# ;Rank 4
# 10185:28=36,30=117,58=2,59=6,60=77,80=28,86=14,88=0,89=3,91=0
# ;Rank 5
# 10186:28=36,30=145,58=2,59=6,60=77,80=28,86=14,88=0,89=3,91=0
# ;Rank 6
# 10187:28=36,30=175,58=2,59=6,60=77,80=28,86=14,88=0,89=3,91=0
#
# ;Hurricane
# ;Rank 1
# 16914:28=36,30=88,58=2,59=6,60=77,88=0,91=0
# ;Rank 2
# 17401:28=36,30=118,58=2,59=6,60=77,88=0,91=0
# ;Rank 3
# 17402:28=36,30=150,58=2,59=6,60=77,88=0,91=0
#
# ;Starshards
# ;Rank 1
# 10797:28=36,30=9,58=2,59=6,60=77,80=6,88=0,89=3,91=0
# ;Rank 2
# 19296:28=36,30=15,58=2,59=6,60=77,80=6,88=0,89=3,91=0
# ;Rank 3
# 19299:28=36,30=24,58=2,59=6,60=77,80=6,88=0,89=3,91=0
# ;Rank 4
# 19302:28=36,30=32,58=2,59=6,60=77,80=6,88=0,89=3,91=0
# ;Rank 5
# 19303:28=36,30=41,58=2,59=6,60=77,80=6,88=0,89=3,91=0
# ;Rank 6
# 19304:28=36,30=50,58=2,59=6,60=77,80=6,88=0,89=3,91=0
# ;Rank 7
# 19305:28=36,30=59,58=2,59=6,60=77,80=6,88=0,89=3,91=0
#
# ;Arcane Missiles
# ;Rank 1
# 5143:11=0,30=0,58=0,59=0,60=77,79=0,80=0,81=0,88=0,90=0,91=0
# ;Rank 2
# 5144:11=0,30=0,58=0,59=0,60=77,79=0,80=0,81=0,88=0,90=0,91=0
# ;Rank 3
# 5145:11=0,30=0,58=0,59=0,60=77,79=0,80=0,81=0,88=0,90=0,91=0
# ;Rank 4
# 8416:11=0,30=0,58=0,59=0,60=77,79=0,80=0,81=0,88=0,90=0,91=0
# ;Rank 5
# 8417:11=0,30=0,58=0,59=0,60=77,79=0,80=0,81=0,88=0,90=0,91=0
# ;Rank 6
# 10211:11=0,30=0,58=0,59=0,60=77,79=0,80=0,81=0,88=0,90=0,91=0
# ;Rank 7
# 10212:11=0,30=0,58=0,59=0,60=77,79=0,80=0,81=0,88=0,90=0,91=0
# ;Rank 8
# ;25345:11=0,30=0,58=0,59=0,60=77,79=0,80=0,81=0,88=0,90=0,91=0
#
# ;Arcane Missile (left for compatibility with Seatleson's)
# ;Rank 1
# 7268:30=29,60=77
# ;Rank 2
# 7269:30=35,60=77
# ;Rank 3
# 7270:30=47,60=77
# ;Rank 4
# 8419:30=64,60=77
# ;Rank 5
# 8418:30=82,60=77
# ;Rank 6
# 10273:30=100,60=77
# ;Rank 7
# 10274:30=119,60=77
# ;Rank 8
# ;25346:30=131,60=77
#
# ;Restore original learning of Arcane Missiles
# ;Rank 1
# 5146:106=5143
# ;Rank 2
# 5147:106=5144
# ;Rank 3
# 5148:106=5145
# ;Rank 4
# 8420:106=8416
# ;Rank 5
# 8421:106=8417
# ;Rank 6
# 10213:106=10211
# ;Rank 7
# 10214:106=10212
# ;Rank 8
# ;25416:106=25345
#
#
# ;Mind Flay
# ;Rank 1
# 15407:28=36,30=15,58=2,59=6,60=77,88=0,91=0
# ;Rank 2
# 17311:28=36,30=24,58=2,59=6,60=77,88=0,91=0
# ;Rank 3
# 17312:28=36,30=34,58=2,59=6,60=77,88=0,91=0
# ;Rank 4
# 17313:28=36,30=45,58=2,59=6,60=77,88=0,91=0
# ;Rank 5
# 17314:28=36,30=55,58=2,59=6,60=77,88=0,91=0
# ;Rank 6
# 18807:28=36,30=69,58=2,59=6,60=77,88=0,91=0
#
# ;Tranquility
# ;Rank 1
# 740:28=36,30=38,58=10,59=6,60=77,79=21,80=21,86=14,88=0,89=8,91=0
# ;Rank 2
# 8918:28=36,30=51,58=10,59=6,60=77,79=21,80=21,86=14,88=0,89=8,91=0
# ;Rank 3
# 9862:28=36,30=70,58=10,59=6,60=77,79=21,80=21,86=14,88=0,89=8,91=0
# ;Rank 4
# 9863:28=36,30=93,58=10,59=6,60=77,79=21,80=21,86=14,88=0,89=8,91=0
#
# ;Rain of Fire
# ;Rank 1
# 5740:28=36,30=37,58=2,59=6,60=77,80=28,86=14,88=0,89=3,91=0
# ;Rank 2
# 6219:28=36,30=76,58=2,59=6,60=77,80=28,86=14,88=0,89=3,91=0
# ;Rank 3
# 11677:28=36,30=111,58=2,59=6,60=77,80=28,86=14,88=0,89=3,91=0
# ;Rank 4
# 11678:28=36,30=149,58=2,59=6,60=77,80=28,86=14,88=0,89=3,91=0
#
# ;Evocation
# 12051:21=31788,28=36,30=0,58=30,59=6,60=77,73=999,74=0,80=1,88=0,89=85,91=0
#
# ;Drain Mana
# ;Rank 1
# 5138:28=36,30=19,58=8,59=6,60=77,70=0,73=41,74=0,80=6,88=0,89=24,91=0,92=1000,94=0
# ;Rank 2
# 6226:28=36,30=31,58=8,59=6,60=77,70=0,73=67,74=0,80=6,88=0,89=24,91=0,92=1000,94=0
# ;Rank 3
# 11703:28=36,30=45,58=8,59=6,60=77,70=0,73=98,74=0,80=6,88=0,89=24,91=0,92=1000,94=0
# ;Rank 4
# 11704:28=36,30=62,58=8,59=6,60=77,70=0,73=135,74=0,80=6,88=0,89=24,91=0,92=1000,94=0
#
# ;Drain Life
# ;Rank 1
# 689:28=36,30=11,58=9,59=6,60=77,80=6,88=0,89=53,91=0,92=1000,94=0
# ;Rank 2
# 699:28=36,30=17,58=9,59=6,60=77,80=6,88=0,89=53,91=0,92=1000,94=0
# ;Rank 3
# 709:28=36,30=27,58=9,59=6,60=77,80=6,88=0,89=53,91=0,92=1000,94=0
# ;Rank 4
# 7651:28=36,30=37,58=9,59=6,60=77,80=6,88=0,89=53,91=0,92=1000,94=0
# ;Rank 5
# 11699:28=36,30=48,58=9,59=6,60=77,80=6,88=0,89=53,91=0,92=1000,94=0
# ;Rank 6
# 11700:28=36,30=60,58=9,59=6,60=77,80=6,88=0,89=53,91=0,92=1000,94=0
#;< end of patch cut until here>


# variables
namespace eval ::ngChanneling {
	variable VERSION 0.1.0

	# delay last_time duration pos target spellid
	variable Data

	variable Time 0

	variable TriggerSpells
	array set TriggerSpells {
		5143 7268
		5144 7269
		5145 7270
		8416 8419
		8417 8418
		10211 10273
		10212 10274
		25345 25346
	}
}

# trigger channeling spell
proc ::ngChanneling::Trigger { to from spellid } {
	variable Data
	variable TriggerSpells
	set target [ ::GetSelection $from ]

	if { $target } {
		set duration [ lindex $::AI::SpellData($spellid) 2 ]
		set Data($from) [ list 1 [ clock seconds ] $duration [ ::GetPos $from ] $target $TriggerSpells($spellid) ]
	}
}

# maintain channeling spell
proc ::ngChanneling::Maintain { to from spellid } {
	variable Data

	if { ! [ info exists Data($from) ] } {
		set duration [ expr { [ lindex $::AI::SpellData($spellid) 2 ] - 1 } ]
		set Data($from) [ list 1 [ clock seconds ] $duration [ ::GetPos $from ] $to $spellid ]
	}
}

# maintain area spell every 1s
proc ::ngChanneling::MaintainArea1 { to from spellid } {
	variable Data

	if { ! [ info exists Data($from) ] } {
		set duration [ expr { [ lindex $::AI::SpellData($spellid) 2 ] - 1 } ]
		set Data($from) [ list 1 [ clock seconds ] $duration [ ::GetPos $from ] $from $spellid ]
	}
}

# maintain area spell every 2s
proc ::ngChanneling::MaintainArea2 { to from spellid } {
	variable Data

	if { ! [ info exists Data($from) ] } {
		set duration [ expr { [ lindex $::AI::SpellData($spellid) 2 ] - 2 } ]
		set Data($from) [ list 2 [ clock seconds ] $duration [ ::GetPos $from ] $from $spellid ]
	}
}

# autoshot (wand and bow)
proc ::ngChanneling::AutoShot { to from spellid } {
	variable Data

	if { ! [ info exists Data($from) ] } {
		set Data($from) [ list 2 [ clock seconds ] 3600 [ ::GetPos $from ] $to $spellid ]
	}
}

# channeling handler
proc ::ngChanneling::Handler {} {
	set time [ clock seconds ]

	if { $time != $::ngChanneling::Time } {
		set ::ngChanneling::Time $time

		foreach caster [ array names ::ngChanneling::Data ] {
			foreach { delay last_time duration pos target spellid } $::ngChanneling::Data($caster) {}

			if { $delay > $time - $last_time } {
				continue
			}

			if { $duration > 0 && [ ::GetObjectType $caster ] && $pos == [ ::GetPos $caster ] && [ ::GetObjectType $target ] && [ ::GetHealthPCT $target ] } {
				::CastSpell $caster $target $spellid
				lset ::ngChanneling::Data($caster) 1 $time
				lset ::ngChanneling::Data($caster) 2 [ expr { $duration - $delay } ]
			} else {
				unset ::ngChanneling::Data($caster)
			}
		}
	}
}

# initialization
proc ::ngChanneling::Init {} {

	# hook the handler
	foreach proc { ::AI::CanUnAgro ::WoWEmu::DamageReduction } {
		::Custom::HookProc $proc [ info body ::ngChanneling::Handler ]
	}

	# decrease duration when hit
	::Custom::HookProc "::WoWEmu::DamageReduction" {
		if { [ info exists ::ngChanneling::Data($player) ] } {
			lset ::ngChanneling::Data($player) 2 [ expr { [ lindex $::ngChanneling::Data($player) 2 ] - 1 } ]
		}
	}

	# Arcane Missiles
	::Custom::AddSpellScript "::ngChanneling::Trigger" [ array names ::ngChanneling::TriggerSpells ]

	# Arcane Missile, Starshards, Mind Flay, Drain Mana, Drain Life
	::Custom::AddSpellScript "::ngChanneling::Maintain" {
		7268 7269 7270 8419 8418 10273 10274 25346
		10797 19296 19299 19302 19303 19304 19305
		15407 17311 17312 17313 17314 18807
		5138 6226 11703 11704
		689 699 709 7651 11699 11700
	}

	# Hurricane, Blizzard, Evocation
	::Custom::AddSpellScript "::ngChanneling::MaintainArea1" {
		16914 17401 17402
		10 6141 8427 10185 10186 10187
		12051
	}

	# Tranquility, Rain of Fire
	::Custom::AddSpellScript "::ngChanneling::MaintainArea2" {
		740 8918 9862 9863
		5740 6219 11677 11678
	}

	# Auto Shot, Shoot
	::Custom::AddSpellScript "::ngChanneling::AutoShot" { 75 5019 }

	::StartTCL::Provide
}


::ngChanneling::Init
